from Ledger import Ledger
from login import login
import util
import file

current_ledger_list = file.get_leger_list_from_file("ledger.txt")


def common_system():
    print("普通用户界面")


def select_by_condition(**condition):
    ll = current_ledger_list
    filter_ledger = [item for item in ll if all(getattr(item, key) == value for key, value in condition.items())]
    my_print(filter_ledger)


def select_by():
    olist = ["根据类别查询", "根据收支查询", "根据账户查询",
             "根据金额查询", "根据时间查询", "根据说明查询",
             "退出查询"]
    # 选择修改操作
    condition = {}
    while True:
        oi = int(util.option_input(olist))
        if oi == 1:
            new_type = input("请输入类别：")
            condition['type'] = new_type
        elif oi == 2:
            res = util.valid_option("请输入是收入还是支出（i 收入/o 支出）：", 'i', 'o')
            new_i_or_o = "收入" if res else "支出"
            condition['i_or_o'] = new_i_or_o
        elif oi == 3:
            new_account = input("请输入账户：")
            condition['account'] = new_account
        elif oi == 4:
            new_amount = input("请输入金额：")
            condition['amount'] = new_amount
        elif oi == 5:
            new_time = input("请输入时间：")
            condition['new_time'] = new_time
        elif oi == 6:
            new_remark = input("请输入说明：")
            condition['new_remark'] = new_remark
        elif oi == 7:
            print("退出查询")
            break
        res = util.yn_option("是否继续修改？（y 是/n 否）：")
        if res is False:
            print("退出修改")
            break


def my_print(ledgers):
    # 定义表头
    headers = ["ID", "类别", "收入支出", "账户", "金额", "时间", "说明"]
    # 手动设置每列的固定宽度为200
    column_widths = [20] * len(headers)

    # 格式化表头
    title = " | ".join(header.ljust(width) for header, width in zip(headers, column_widths))
    print(title)
    print("-" * len(title))  # 打印分隔线

    # 格式化每一行的内容
    for item in ledgers:
        columns = str(item).strip().split("\t")
        row = " | ".join(col.ljust(width) for col, width in zip(columns, column_widths))
        print(row)


def select_ledger():
    option_list = ["查询所有", "按条件查询"]
    opt_num = util.option_input(option_list)
    if opt_num == 1:
        print(current_ledger_list)
    elif opt_num == 2:
        select_by()


def del_ledger():
    ledger_l = current_ledger_list
    print("现有账单如下：")
    my_print(ledger_l)
    input_id = util.valid_id_input(ledger_l)
    print(input_id)
    for item in ledger_l:
        if item.id == str(input_id):
            ledger_l.remove(item)
    print("删除后的账单如下：")
    my_print(ledger_l)
    file.write_to_file(ledger_l, 'w')


def get_new_value(prompt):
    return input(prompt)


def modify_attribute(ledger, attribute, prompt):
    new_value = get_new_value(prompt)
    setattr(ledger, attribute, new_value)


def update_ledger(ledger):
    olist = ["修改类别", "修改收支", "修改账户", "修改金额", "修改时间", "修改说明", "退出修改"]
    attributes_map = {
        1: ("type", "请输入新的类别："),
        2: ("in_or_out", "请输入是修改为收入还是支出（i 收入/o 支出）："),
        3: ("account", "请输入新账户："),
        4: ("amount", "请输入新的金额："),
        5: ("time", "请输入新的时间："),
        6: ("remark", "请输入新的说明：")
    }
    # 选择修改操作
    print(f"被修改的对象为：{ledger}")
    while True:
        # 合法化输出
        oi = int(util.option_input(olist))
        for i, option in enumerate(olist, start=1):
            print(f"{i}. {option}")
        oi = int(util.option_input(olist))
        if oi == 7:
            print("退出修改")
            break
        attribute, prompt = attributes_map[oi]
        if attribute == "in_or_out":
            res = util.valid_option(prompt, 'i', 'o')
            new_i_or_o = "收入" if res else "支出"
            ledger.in_or_out = new_i_or_o
        else:
            modify_attribute(ledger, attribute, prompt)
        res = util.yn_option("是否继续修改？（y 是/n 否）：")
        if res is False:
            print("退出修改")
            break


def edit_ledger():
    ledger_l = current_ledger_list
    print("现有账单如下：")
    my_print(ledger_l)
    # 选取账户对象
    input_id = util.valid_id_input(ledger_l)
    updated_ledger = [item for item in ledger_l if item.id == str(input_id)][0]
    # 进行修改操作
    update_ledger(updated_ledger)
    print("修改后的结果")
    my_print(ledger_l)
    # 把修改的结果同步到文件
    file.write_to_file(ledger_l, 'w')


def add_input(l_id):
    input_type = input("请输入类型：")
    res = util.valid_option("请输入是收入还是支出（i 收入/o 支出）：", 'i', 'o')
    i_or_n = "收入" if res else "支出"
    input_account = input("请输入账户：")
    input_amount = input("请输入金额：")
    input_time = input("请输入时间：")
    input_remark = input("请输入说明：")
    return Ledger(l_id, input_type, i_or_n, input_account, input_amount, input_time, input_remark)


# 添加账务
def add_ledger():
    # 获取当前账单列表
    ledger_list = current_ledger_list
    while True:
        idx = len(ledger_list)
        lasted_id = int(ledger_list[idx - 1].id)
        print(lasted_id)
        ledger = add_input(lasted_id + 1)
        ledger_list.append(ledger)
        res = util.yn_option("是否继续添加账单（y 是/n 否）：")
        if res is False:
            break
    # 结束输入，将信息同步到current_ledger_list，并保存到文件中
    file.write_to_file(ledger_list, 'w')


# 管理员系统
def admin_system():
    print("管理端界面")
    option_list = ["添加账务", "编辑账务", "删除账务", "查询账务", "退出系统"]
    while True:
        opt_count = util.option_input(option_list)
        if opt_count == "1":
            add_ledger()
        elif opt_count == "2":
            edit_ledger()
        elif opt_count == "3":
            del_ledger()
        elif opt_count == "4":
            select_ledger()
        elif opt_count == "5":
            print("退出系统成功")
            return


def system():
    print("家庭对账")
    while True:
        role = None
        is_not_first = False
        while role is None:
            if is_not_first:
                if util.re_option("登录"):
                    pass
                else:
                    return
            role = login()
            is_not_first = role is None
        if role == "admin":
            admin_system()
        elif role == "common":
            common_system()

        if util.yn_option("是否退出系统（y 是 / n 否)"):
            return
        else:
            pass


if __name__ == '__main__':
    system()
